home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume10 / ptoc / part05 < prev    next >
Encoding:
Internet Message Format  |  1987-07-26  |  37.8 KB

  1. Path: uunet!rs
  2. From: rs@uunet.UU.NET (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v10i069:  Pascal to C translator, Part05/12
  5. Message-ID: <708@uunet.UU.NET>
  6. Date: 27 Jul 87 23:08:40 GMT
  7. Organization: UUNET Communications Services, Arlington, VA
  8. Lines: 1549
  9. Approved: rs@uunet.UU.NET
  10.  
  11. Submitted-by: Per Bergsten <mcvax!enea!chalmers!holtec!perb>
  12. Posting-number: Volume 10, Issue 69
  13. Archive-name: ptoc/Part05
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 5 (of 12)."
  22. # Contents:  ptoc.doc
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f 'ptoc.doc' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'ptoc.doc'\"
  26. else
  27. echo shar: Extracting \"'ptoc.doc'\" \(35411 characters\)
  28. sed "s/^X//" >'ptoc.doc' <<'END_OF_FILE'
  29. X.\"            @(#)doc.ms    1.6 Date 87/06/29
  30. X.if t .rm CM
  31. X.ds LH Holistic Technology AB
  32. X.ds CH PTC
  33. X.ds RH HD870410-1 Rev: 1.6
  34. X.ds LF
  35. X.ds CF
  36. X.ds RF
  37. X.nr LL 6.5i
  38. X.nr PO 1i
  39. X.nr HM 0.75i
  40. X.nr FM 1.5i
  41. X.ie t .pl 842p
  42. X.el   .pl 72v
  43. X.ch BT -\n(FMu/2u
  44. X.\" 3 tabs/inch at 12 cpi corresponds to 4 chars/tab
  45. X.nr t 1i/3u
  46. X.am DS
  47. X.ta \ntu +\ntu +\ntu +\ntu +\ntu +\ntu +\ntu +\ntu +\ntu +\ntu +\ntu +\ntu +\ntu +\ntu +\ntu +\ntu +\ntu +\ntu
  48. X..
  49. X.LP
  50. X.rs
  51. X.sp |8c
  52. X.nf
  53. X.ce 10
  54. X.if t .ps +6
  55. X.B "PTC implementation note"
  56. X.if t .ps -6
  57. X
  58. Xby
  59. X
  60. XPer Bergsten
  61. X
  62. XHolistic Technology AB
  63. XGrona Gatan 59
  64. X414 54 Gothenburg
  65. XSweden
  66. X.ce 0
  67. X.sp 12
  68. X.LP
  69. XThis note describes the implementation of ptc, a Pascal to C translator.
  70. XThe program was developed by Per Bergsten of Holistic Technology AB,
  71. XGothenburg, Sweden.
  72. XThe paper is intended to provide a guide for those who need to transport
  73. Xptc to a new environment,
  74. Xit describes how Pascal constructs are mapped onto C constructs.
  75. X.bp
  76. X.NH S 1
  77. XBackground
  78. X.LP
  79. X.ds CF - % -
  80. X.nr % 1
  81. XThe aim was originally to provide a simple tool for transporting finished
  82. Xapplications to systems lacking Pascal compilers.
  83. XThe first versions,
  84. Xconstructed in about 1984,
  85. Xwere capable of translating simple Pascal programs.
  86. XIt was never intended to become a released product,
  87. Xhowever,
  88. Xas time went by, programs and ambitions grew to the point where nearly
  89. Xthe full Pascal language was supported.
  90. XThus the program as it stands today has a long ancestry
  91. Xbut it has never been redesigned (which it should have been).
  92. X.NH 1
  93. XPascal vs C
  94. X.LP
  95. XTo anyone familiar with the two languages it is obvious that
  96. Xthey are very similar in structure.
  97. XThe major features may be summarised as follows:
  98. X.TS
  99. Xc c
  100. Xl l .
  101. XPascal    C
  102. X.sp
  103. XBlock-structured    Block-structured
  104. X- multiple declaration levels    - single declaration level
  105. XStatically scoped    Statically scoped
  106. XStrongly typed    Weakly typed
  107. X    - allows unbounded pointers
  108. XCall by value    Mostly call by value
  109. X- and call by reference    
  110. XHighly independent    Highly integrated
  111. X- of host system    - with system
  112. XSelf contained    Allows external definitions.
  113. X.TE
  114. X.LP
  115. XOn the syntactic level the languages differ only in minor ways,
  116. Xmostly in the order in which keywords and other symbols occur,
  117. Xand of course in that the languages uses different symbols for the same
  118. Xpurposes.
  119. XThe only complication is that C prohibits nested subroutine declarations.
  120. X.LP
  121. XOn the semantic level the situation is worse.
  122. XC has the peculiarity that array variables are treated differently from other
  123. Xvariables,
  124. Xthis forces us to adopt some general way to handle array variables.
  125. XFurthermore, since Pascal offers nested subroutine declarations
  126. Xit becomes necessary to simulate part of the activation record mechanism
  127. Xin the translated code,
  128. Xin one case it is extremely difficult to completely do this.
  129. XIt is also clear that the C typedef mechanism has some shortcomings that
  130. Xpreclude an easy translation of Pascal types.
  131. X.bp
  132. X.NH 1
  133. XMapping Pascal to C
  134. X.LP
  135. XIn this part of the paper we briefly illustrate how to translate
  136. XPascal code into equivalent C code.
  137. X.NH 2
  138. XPrograms
  139. X.LP
  140. XA minimal Pascal program:
  141. X.DS
  142. Xprogram p;
  143. Xbegin
  144. Xend.
  145. X.DE
  146. Xtranslates to the C equivalent:
  147. X.DS
  148. Xextern void exit(\^);
  149. Xmain(\^)
  150. X{
  151. X        exit(0);
  152. X}
  153. X.DE
  154. X.LP
  155. XIt should be noted here that
  156. Xthe translator does not actually require a complete Pascal program,
  157. Xthe implementation is such that any consistent set of declarations can
  158. Xbe translated.
  159. X.NH 2
  160. XLexical issues
  161. X.LP
  162. XThe C language uses ASCII as a carrier,
  163. Xalmost all of the availible characters are used.
  164. XThe Pascal definition uses a smaller set of characters.
  165. XSince few features of the languages depend on the underlying character set
  166. Xthis does not introduce much difficulties.
  167. X.LP
  168. XOne serious problem does occur.
  169. XBoth language definitions states that comments have no meaning and no
  170. Xclear place in the language syntax.
  171. XFurthermore, the Pascal definition states that a comment is equivalent
  172. Xto a blank character.
  173. XThis implies that if comments are handled accurately
  174. Xthe translator should also be able to collect and classify each
  175. Xblank character in a Pascal program and to generate a C program with the
  176. Xsame number of blank characters in the corresponding positions.
  177. XThis implication conflicts with the fact that the languages have different
  178. Xsyntax rules, it is not obvious what the "corresponding positions" would be.
  179. X.LP
  180. XSince comments have no defined meaning a user is free to interpret them
  181. Xin any way and, in particular, to associate them with the surrounding code
  182. Xin any way s/he chooses.
  183. XAlthough humans usually are able to deduce what bearing a comment has on the
  184. Xsurrounding program code there are no formal rules for how to do this.
  185. XTherefore there is no
  186. X.I "a priori"
  187. Xcorrect way to translate comments
  188. Xand the translator described here ignores comments altogether.
  189. XIf/when a reasonable
  190. X.I "ad hoc"
  191. Xsolution is found that feature may be incorporated.
  192. X.NH 2
  193. XDeclarations
  194. X.LP
  195. XThe program may introduce local declarations which are handled as follows.
  196. X.bp
  197. X.NH 3
  198. XLabels
  199. X.LP
  200. X.DS
  201. Xprogram p;
  202. X
  203. Xlabel    9;
  204. X
  205. Xbegin
  206. X9:
  207. X        goto 9
  208. Xend.
  209. X.DE
  210. Xwhich we simply translate into:
  211. X.DS
  212. Xextern void exit(\^);
  213. Xmain(\^)
  214. X{
  215. XL9:
  216. X        goto L9;
  217. X        exit(0);
  218. X}
  219. X.DE
  220. X'ne 12
  221. X.LP
  222. XIf the label is reached from an inner procedure:
  223. X.DS
  224. Xprogram p;
  225. X
  226. Xlabel    100;
  227. X
  228. X        procedure q;
  229. X
  230. X        begin
  231. X                goto 100
  232. X        end;
  233. X
  234. Xbegin
  235. X100:
  236. Xend.
  237. X.DE
  238. Xa more complicated translation must be used:
  239. X.DS
  240. X# define Line __LINE__
  241. Xvoid Caseerror(\^);
  242. X# include <setjmp.h>
  243. Xstatic struct Jb { jmp_buf jb; } J[1];
  244. X
  245. X void
  246. Xq(\^)
  247. X{
  248. X        longjmp(J[0].jb, 100);
  249. X}
  250. X
  251. Xmain(\^)
  252. X{
  253. X        if (setjmp(J[0].jb))
  254. X                goto L100;
  255. XL100:
  256. X        exit(0);
  257. X}
  258. X.DE
  259. X.LP
  260. XWe assume the existence of the standard
  261. X.I setjmp(\^)
  262. Xand
  263. X.I longjmp(\^)
  264. Xlibrary functions.
  265. XJumpbuffers are statically allocated as needed depending on the number
  266. Xof declarationlevels in the program.
  267. X.NH 3
  268. XConstants
  269. X.LP
  270. XConstant declarations are treated in two different ways.
  271. XNumbers aliases etc are simply
  272. X.I "# define" 'd
  273. Xbut string constants are converted to static character arrays in order
  274. Xto avoid unnecessary duplication of string-constants in the object code,
  275. Xthus:
  276. X.DS
  277. Xconst
  278. X    p    = 3.14;
  279. X    pie    = '3.14';
  280. X.DE
  281. Xtranslates to:
  282. X.DS
  283. X# define pi 3.14
  284. Xstatic char pie[\^] = "3.14";
  285. X.DE
  286. X.NH 3
  287. XTypes and variables
  288. X.LP
  289. XTypes and variables are mostly easy to translate:
  290. X.DS
  291. Xprogram p;
  292. X
  293. Xconst length    = 15;
  294. X
  295. Xtype
  296. X    struct        = 0 .. length;
  297. X    vect        = array [ struct ] of struct;
  298. X    color        = (red, blue, ada, yellow);
  299. X    pointer    = ^ recd;
  300. X    recd        = record
  301. X                r    : pointer;
  302. X                case b : boolean of
  303. X                  false:    (c : color);
  304. X                  true:    (v : vect);
  305. X              end;
  306. X
  307. Xvar    SP        : pointer;
  308. X
  309. Xbegin
  310. X    new(SP, true);
  311. Xend.
  312. X.DE
  313. Xbecomes
  314. X.DS
  315. Xtypedef char    boolean;
  316. X# define false (boolean)0
  317. X# define true (boolean)1
  318. Xextern char *Bools[\^];
  319. X# define Unionoffs(p, m) (((long)(&(p)->m))-((long)(p)))
  320. Xextern char *malloc(\^);
  321. X# define length 15
  322. Xtypedef unsigned char C47_struct;
  323. Xtypedef struct { C47_struct A[length + 1]; } vect;
  324. Xtypedef enum { red, blue, ada, yellow } color;
  325. Xtypedef struct S57 *pointer;
  326. Xtypedef struct S57 {
  327. X    pointer    r;
  328. X    boolean    b;
  329. X    union {
  330. X        struct {
  331. X            color    c;
  332. X        } V1;
  333. X        struct  {
  334. X            vect    v;
  335. X        } V2;
  336. X    } U;
  337. X}    recd;
  338. Xpointer    sp;
  339. X
  340. Xmain(\^)
  341. X{
  342. X    sp = (struct S57 *)malloc((unsigned)
  343. X        (Unionoffs(sp, U.V2.v) + sizeof(sp->U.V2)));
  344. X    exit(0);
  345. X}
  346. X.DE
  347. XThe rationale is as follows:
  348. X.LP
  349. XIdentifiers in the Pascal program which conflicts with reserved words in C are
  350. Xrenamed by adding a unique prefix Cnnn where nnn is a number.
  351. X.LP
  352. XWe also note here that uppercase letters in identifiers and keywords
  353. Xare translated to lowercase.
  354. XPascal specifies that upper/lower case is insignificant whereas C
  355. X(for the present) separates the two.
  356. XThis fact is used to advantage by the translator as all
  357. Xsubroutines and macros defined by the translator have an initial uppercase
  358. Xletter which prevents confusion.
  359. X.IP \-
  360. XThe type
  361. X.I boolean
  362. Xis a predefined Pascal type,
  363. Xwhen it is used the translator emits code which defines boolean to
  364. Xbe the smallest convenient type:
  365. X.I char .
  366. XThe constants
  367. X.I false
  368. Xand
  369. X.I true
  370. Xare defined and the vector
  371. X.I Bools
  372. Xwill contain textstrings for output if needed.
  373. X.IP \-
  374. XThe predefined types
  375. X.I integer
  376. Xand
  377. X.I real
  378. Xare likewise mapped directly onto the standard C types
  379. X.I int
  380. Xand
  381. X.I double
  382. Xthrough a typedef declaration.
  383. X.sp
  384. XInteger subranges are mapped onto standard C arithmetic types according to
  385. Xa short table in the translator.
  386. XThe table is scanned from top to bottom until an enclosing range is found
  387. Xand the corresponding type-name is emitted.
  388. X.IP \-
  389. XC-arrays have peculiar semantix.
  390. XTo unify the treatment of arrays and other datatypes we always encapsulate
  391. Xan array in a struct,
  392. Xthus an array always becomes a
  393. X.I struct
  394. Xwith a single member named A.
  395. X.IP \-
  396. XRecords and their variants are translated into C
  397. X.I struct
  398. Xand
  399. X.I union
  400. Xdefinitions.
  401. XSince C requires all union members to have a name we must supply artificial
  402. Xnames for all record variants.
  403. XA record with variants will therefore always contain one field with the name U
  404. Xwhich have sub-fields named Vnnn where nnn is a positive number.
  405. X.sp
  406. X'ne 12
  407. XWhen allocating dynamic storage for a record with variants naming
  408. Xthe desired variant
  409. X.DS
  410. Xnew(sp, true)
  411. X.DE
  412. Xwe face the problem of determining the amount of memory needed.
  413. X.QP
  414. X.B
  415. XC does not provide a safe way
  416. Xto compute the size of a particular struct variant.
  417. X.IP
  418. XThe strategy adopted to cope with this problem is to attempt to compute the
  419. Xoffset of a fieldmember in the variant matching the constant and then
  420. Xto add the size of the variant.
  421. XThe offset computation is expressed as a macro,
  422. X.I Unionoffs ,
  423. Xwhich uses rather foul typecasting to achive the result.
  424. XThe only availible alternative would be to use the same size of all variants.
  425. XThis method,
  426. Xwhile being safe,
  427. Xwastes memory when many small and few large
  428. Xrecords of the same type are created dynamically.
  429. X.IP \-
  430. XPascal enumeration types are converted directly to C
  431. X.I enum
  432. Xtypes.
  433. X.IP \-
  434. XPascal pointer types are translated into C pointer types.
  435. XPascal allows the programmer to construct recursive types as pointer
  436. Xtypes need not be fully defined until the end of the declaration-section
  437. Xwhere the pointer type is used.
  438. XIn practice this is only used to introduce record types which
  439. Xcontain pointers to themselves.
  440. XThis problem is partially solved by introducing a name for the record type.
  441. X.ne 10
  442. XHence
  443. X.DS
  444. Xtype
  445. X    ptr    = ^ node;
  446. X    node    = record
  447. X            next    : ptr;
  448. X            info    : integer
  449. X          end;
  450. X.DE
  451. Xbecomes
  452. X.DS
  453. Xtypedef struct S56 * ptr;
  454. Xtypedef struct S56 {
  455. X    ptr        next;
  456. X    integer        info;
  457. X} node;
  458. X.DE
  459. Xwe note in passing that the problem cannot be completely solved since
  460. X.DS
  461. Xtype    pureptr    = ^ pureptr;
  462. X.DE
  463. Xwhich is valid Pascal, cannot be expressed in C.
  464. X.ne 10v
  465. X.IP \-
  466. XA pascal set-type does not have any direct counterpart in C.
  467. XThe C language does however have a adequate set of operators for
  468. Xbit manipulation.
  469. XWe use these to implement a Pascal set as an array of
  470. X.I setword .
  471. XSo:
  472. X.DS
  473. Xtype
  474. X    s    = set of 1 .. 100;
  475. X
  476. Xvar
  477. X    ss    : s;
  478. X.DE
  479. Xis translated into:
  480. X.DS
  481. Xtypedef unsigned short setword;
  482. Xtypedef struct { setword S[8]; } s;
  483. X
  484. Xs    ss;
  485. X.DE
  486. XThe situation is slightly complicated by the fact that Pascal has
  487. Xa set constructor which permits the construction of arbitrary large sets,
  488. Xfor example:
  489. X.DS
  490. Xs := [ 50 .. maxint ] * [ 1 .. 80 ]
  491. X.DE
  492. Xfor that reason the first member in the array of words gives
  493. Xsize of the set (in words).
  494. XIn the example above s.S[0] would have the value 7,
  495. Xand s.S[1] through s.S[7] would hold the bits.
  496. XThe number 7 is computed on the assumption that the type
  497. X.I "unsigned short"
  498. Xon the target host is sufficiently large to holds 16 bits.
  499. XThe set operators of Pascal are implemented as C functions returning
  500. Xpointers to arrays of setwords,
  501. Xthe intermediary results are held in a static area of fixed size.
  502. X.IP \-
  503. XPascal files are implemented using the standard i/o package availible
  504. Xin most C implementations.
  505. XSince Pascal has the requirement that the next element of a file is visible
  506. Xin the filebuffer before it is read,
  507. Xand the requirement that linemarkers in textfiles are given special treatement
  508. Xwe are forced to extend the
  509. X.I FILE
  510. Xtype provided in
  511. X.I <stdio.h> .
  512. X.ne 20
  513. XHence:
  514. X.DS
  515. Xvar    f    : text;
  516. X.DE
  517. Xbecomes
  518. X.DS
  519. Xtypedef struct {
  520. X    FILE    *fp;
  521. X    unsigned short
  522. X            eoln:1,
  523. X            eof:1,
  524. X            init:1,
  525. X            out:1,
  526. X            :12;
  527. X    char    buf;
  528. X}    text;
  529. Xtext    f;
  530. X.DE
  531. Xwhere
  532. X.I buf
  533. Xis our filebuffer and
  534. X.I eoln ,
  535. X.I eof
  536. Xand
  537. X.I init
  538. Xare flags giving the state of the file.
  539. XAll Pascal i/o operations are implemented using macros that maintain the flags
  540. Xand the buffer variable.
  541. XThe actual reading and writing of data is deferred to the standard i/o package.
  542. X.NH 3
  543. XProcedures and functions
  544. X.LP
  545. XPascal procedures and functions are somewhat difficult to translate to C.
  546. XThe main problems lie in nested declarations and procedural parameters.
  547. XNested declarations are handled in the following manner:
  548. X.RS
  549. X.IP \-
  550. XIf procedure B is declared in procedure A,
  551. Xthen procedure B is emitted before A and A is forward declared before B.
  552. X.IP \-
  553. XAny constants and types declared in A is moved to the global scope,
  554. Xthis may force renaming of those objects.
  555. X.IP \-
  556. XAny variable declared in A
  557. X.I
  558. Xand used in B
  559. X.R
  560. Xis converted to a pointer and moved to the global scope.
  561. XThe pointer value is saved and re-initialized upon each entry of A
  562. Xand restored upon exit from A.
  563. X.RE
  564. X.br
  565. X'ne 20
  566. X.LP
  567. XHence:
  568. X.DS
  569. Xprocedure A;
  570. X
  571. Xconst    limit    = 20;
  572. X
  573. Xtype    loctyp    = 0 .. limit;
  574. X
  575. Xvar    i, j    : loctyp;
  576. X
  577. X    procedure B(k : loctyp);
  578. X
  579. X    begin
  580. X        j := k + 2
  581. X    end;
  582. X
  583. Xbegin
  584. X    B(i)
  585. Xend;
  586. X.DE
  587. Xbecomes
  588. X.DS
  589. Xtypedef unsigned char    loctyp;
  590. Xloctyp    *G56_j;
  591. X
  592. Xvoid a(\^);
  593. X
  594. X void
  595. Xb(k)
  596. X    loctyp  k;
  597. X{
  598. X    (*G56_j) = k + 2;
  599. X}
  600. X
  601. X void
  602. Xa(\^)
  603. X{
  604. X# define limit 20
  605. X    loctyp  i, j;
  606. X    loctyp  *F57;
  607. X
  608. X    F57 = G56_j;
  609. X    G56_j = &j;
  610. X    b(i);
  611. X    G56_j = F57;
  612. X}
  613. X.DE
  614. Xwe see that references to
  615. X.I j
  616. Xinside procedure
  617. X.I b
  618. Xare replaced by the pointer
  619. X.I G56_j
  620. Xwhich points to the local variable
  621. X.I j
  622. Xin procedure
  623. X.I a.
  624. XIn order to preserve the proper semantix in the face of recursion
  625. Xthe value of the pointer need also be saved in the local variable
  626. X.I F57
  627. Xduring the invocation of
  628. X.I a .
  629. X.IP \-
  630. XProcedure parameters offer little problems.
  631. XWe translate Pascal value-parameters into ordinary C parameters
  632. Xand Pascal var-parameters are treated as pointers.
  633. X.br
  634. X'ne 20
  635. X.IP \-
  636. XProcedural parameters appear at first to be easy to handle.
  637. XThe ordinary program:
  638. X.DS
  639. Xprogram p;
  640. X
  641. Xprocedure pp(procedure q(i : integer));
  642. X
  643. Xbegin
  644. X    q(2)
  645. Xend;
  646. X
  647. Xprocedure qq(i : integer);
  648. Xbegin
  649. Xend;
  650. X
  651. Xbegin
  652. X    pp(qq)
  653. Xend.
  654. X.DE
  655. Xbecomes
  656. X.DS
  657. Xextern void    exit(\^);
  658. Xtypedef int    integer;
  659. X
  660. X void
  661. Xpp(q)
  662. X    void    (*q)(\^);
  663. X{
  664. X    (*q)(2);
  665. X}
  666. X
  667. X void
  668. Xqq(i)
  669. X    integer i;
  670. X{
  671. X}
  672. X
  673. Xmain(\^)
  674. X{
  675. X    pp(qq);
  676. X    exit(0);
  677. X}
  678. X.DE
  679. Xwhich looks simple enough.
  680. X.br
  681. XHowever,
  682. XPascal requires that the scope of a procedure
  683. X.I "remains unchanged"
  684. Xthroughout its lifetime.
  685. X.ne 35
  686. XConsider:
  687. X.DS
  688. Xprogram demo(output);
  689. X
  690. Xvar    i    : integer;
  691. X
  692. X    procedure p(procedure q);
  693. X
  694. X    var    j    : integer;
  695. X
  696. X        procedure qq;
  697. X
  698. X        begin
  699. X            writeln(j)
  700. X        end;
  701. X
  702. X    begin
  703. X        j := i;
  704. X        q;
  705. X        if i < 1 then
  706. X          begin
  707. X            i := i + 1;
  708. X            p(qq)
  709. X          end
  710. X    end;
  711. X
  712. X    procedure dummy;
  713. X    begin
  714. X    end;
  715. X
  716. Xbegin
  717. X    i := 0;
  718. X    p(dummy)
  719. Xend.
  720. X.DE
  721. XWhen
  722. X.I p
  723. Xis first invoked it assigns the local variable
  724. X.I j
  725. Xthe value 0.
  726. XThis variable is accessible from
  727. X.I qq
  728. Xwhich is passed as a parameter in
  729. Xthe recursive call of
  730. X.I p .
  731. XThe second invocation of
  732. X.I p
  733. Xthen sets
  734. X.I its 
  735. Xvariable
  736. X.I j
  737. Xto 1,
  738. Xand calls
  739. X.I q
  740. Xwhich is bound to the first instance of
  741. X.I qq ,
  742. Xand should therefore print the number
  743. X.I 0 .
  744. X.B
  745. XSadly,
  746. Xthe code produced by the translator fails to do this.
  747. X.R
  748. XIt is obvious that the program above calls for a complete simulation
  749. Xof the activation record mechanism of Pascal to work correctly.
  750. X.RS
  751. X.LP
  752. XA workable but unpractical solution would be:
  753. X.IP 1)
  754. XWhen qq is used as parameter we call a function q1 which saves the environment
  755. Xfor qq (i.e. the address of j) in a well known place
  756. Xand returns a pointer to q2.
  757. X.IP 2)
  758. XWhen qq is later called (under the name q) the actual target will be q2
  759. Xwhich sets up the proper environment calls qq.
  760. X.RE
  761. X.IP
  762. XThe problem is that this requires a save-area for
  763. X.I each
  764. Xprocedural parameter which can hold the intresting
  765. Xparts of its environment for
  766. X.I each
  767. Xof its invocations.
  768. XIn the example above we need one are which holds the address of i
  769. Xfor each instance of qq
  770. X(say N instances, where N depends on the run-time behaviour of p).
  771. XIt also requires a set of different procedures to perform the work of q2
  772. X(N different procedures which sets up the environment for the N instances).
  773. X.B
  774. XThis requires much to much work to implement so the problem is left unsolved,
  775. X.R
  776. Xthis is hardly a problem in practice since humans rarely write such code
  777. Xbut
  778. X.B
  779. Xit could introduce problems
  780. X.R
  781. Xin machine generated Pascal code.
  782. X.IP
  783. XIt should be noted that
  784. Xthe translator accepts the keyword
  785. X.B external
  786. Xin place of the Pascal
  787. X.B forward
  788. Xdirective and assumes that the so declared procedure is defined elsewhere.
  789. X.bp
  790. X.NH 2
  791. XStatements.
  792. X.LP
  793. XPascal statements are comparatively easy to translate to C.
  794. XThe only parts that require special care are 
  795. Xnon-local
  796. X.I goto ,
  797. X.I with
  798. Xand
  799. X.I for
  800. Xstatements.
  801. XThe code
  802. X.DS
  803. Xprogram p(output);
  804. X
  805. Xtype
  806. X    msgtyp    = packed array [ 1 .. 12 ] of char;
  807. X
  808. Xvar
  809. X    a    : array [ 1 .. 10 ] of
  810. X            record
  811. X                r    : real
  812. X            end;
  813. X    i    : integer;
  814. X    ok    : boolean;
  815. X
  816. X    procedure fatal(m : msgtyp);
  817. X
  818. X    begin
  819. X        writeln('Fatal error: ', m)
  820. X    end;
  821. X
  822. Xbegin
  823. X    while true do
  824. X      repeat
  825. X        ok := false;
  826. X        i := 1;
  827. X        for i := i + 1 to i + 10 do
  828. X            if i > 10 then
  829. X                fatal(' 10 exceeded')
  830. X            else
  831. X              with a[i] do
  832. X                if r > 9.99e+38 then
  833. X                    ok := true
  834. X                else
  835. X                    writeln(r)
  836. X      until ok
  837. Xend.
  838. X.DE
  839. X'ne 20
  840. Xbecomes
  841. X.DS
  842. Xtypedef char boolean;
  843. X# define false (boolean)0
  844. X# define true (boolean)1
  845. Xtypedef int integer;
  846. Xtypedef double real;
  847. X
  848. Xtypedef struct { char A[12 - 1 + 1]; } msgtyp;
  849. Xtypedef struct { struct    S57 {
  850. X    real    r;
  851. X}    A[10 - 1 + 1]; }  T56;
  852. XT56        a;
  853. Xinteger    i;
  854. Xboolean    done;
  855. X
  856. X void
  857. Xfatal(m)
  858. X    msgtyp    m;
  859. X{
  860. X    (void)fprintf(output.fp, "Fatal error: %.12s", m.A),
  861. X                    Putchr('\en', output);
  862. X}
  863. X
  864. Xmain(\^)
  865. X{
  866. X    while (true)
  867. X      do {
  868. X        done = false;
  869. X        i = 1;
  870. X        {
  871. X          integer        B1 = i + 1, B2 = i + 10;
  872. X
  873. X          if (B1 <= B2)
  874. X            for (i = B1; ; i++) {
  875. X                if (i > 10)
  876. X                    fatal(*((msgtyp *)" 10 exceeded"));
  877. X                else {
  878. X                    register struct    S57 *W3 = &a.A[i - 1];
  879. X
  880. X                    if (W3->r > 9.99e+38)
  881. X                        done = true;
  882. X                    else
  883. X                        (void)fprintf(output.fp, "% 20e", W3->r),
  884. X                            Putchr('\en', output);
  885. X                }
  886. X                if (i == B2) break;
  887. X            }
  888. X        }
  889. X      } while (!(done));
  890. X    exit(0);
  891. X}
  892. X.DE
  893. Xfor the following reasons:
  894. X.NH 3
  895. XBegin
  896. X.LP
  897. XThe compound statements
  898. Xare very similar in the two languages and need no further explanation.
  899. X.NH 3
  900. XIf
  901. X.LP
  902. XPascal if-statements
  903. Xhave the same structure and semantix as C if-statments.
  904. X.NH 3
  905. XCase
  906. X.LP
  907. XPascal case-statements
  908. Xhave the same structure and semantix as C switch-statements provided that a
  909. X.I break
  910. Xis always added to each entry.
  911. X.LP
  912. XThe translator supports a common Pascal extension
  913. Xin that it recognizes the keyword
  914. X.B otherwise
  915. Xto signify a default entry in a case-statement.
  916. X.NH 3
  917. XLabels
  918. X.LP
  919. XPascal labeled statements and labels have the same structure and semantix as
  920. XC labeled statements except that Pascal labels are numbers where C labels
  921. Xare identifiers,
  922. Xthis difference is solved by simply prefixing the labels with the letter
  923. X.I L .
  924. X.NH 3
  925. XGoto
  926. X.LP
  927. XPascal goto-statements
  928. Xhave the same structure as C goto statements but the semantix differ in
  929. Xthat Pascal allows a goto to lead out of the current procedure.
  930. XThis is implemented using the
  931. X.I setjmp/longjmp
  932. Xlibrary functions of C as described earlier.
  933. X.NH 3
  934. XWith
  935. X.LP
  936. XThe with-statement
  937. Xof Pascal has no counterpart in C.
  938. XIt is translated into nested compund statements where pointervariables,
  939. Xreferencing the corresponding records,
  940. Xare declared and initialized.
  941. XWithin the scope of the with-statement,
  942. Xthe accessible record fields are renamed to include the pointer.
  943. XThe effect of this is that the record address is evaluated once as the
  944. XPascal standard requires.
  945. X.NH 3
  946. XFor
  947. X.LP
  948. XThe for-statement
  949. Xof Pascal has a structure that is similar to the C for-statement
  950. Xbut the semantix differ completely.
  951. XPascal requires that a loop be exited when the upper bound
  952. Xhas been reached,
  953. XPascal also requires that the loop-boundaries be evaluated exactly once.
  954. XThe standard C for-loop is exited when the loop-condition becomes false.
  955. XThis implies that it is not always true that
  956. X.DS
  957. Xfor (i = 0; i <= e; i++) ;
  958. X.DE
  959. Xbehaves in the same manner as
  960. X.DS
  961. Xfor i := 0 to e do ;
  962. X.DE
  963. Xsince (in most implementations)
  964. Xthe C version becomes an infinite loop if
  965. X.I e
  966. Xequals
  967. X.I maxint
  968. Xor if
  969. X.I e
  970. Xis the expression
  971. X.I i .
  972. XFor that reason Pascal for-statments are translated into compound statements
  973. Xwhere the upper/lower bounds of the for-loop are held in local variables.
  974. XIt is also necessary to add a conditional break-statement at
  975. Xthe end of the loop.
  976. XIt is possible to obtain the more relaxed translation by configuring the
  977. Xtranslator appropriately (see "Tuning" below).
  978. X.NH 3
  979. XWhile
  980. X.LP
  981. XThe while-statement behaves exactly the same in both languages.
  982. X.NH 3
  983. XRepeat
  984. X.LP
  985. XThe repeat-statement of Pascal matches the do-while statement of C except
  986. Xfor the trivial difference that Pascal permits a statement-list
  987. Xwhere C permits a single statment in the loop.
  988. X.NH 3
  989. XEmpty
  990. X.LP
  991. XThe empty statement has (of course) the same structure and semantix
  992. Xin both languages.
  993. X.NH 2
  994. XExpressions and assignments
  995. X.LP
  996. XIn most cases Pascal expressions can be literally translated into equivalent
  997. XC expressions.
  998. X.IP identifiers 15
  999. XExcept where identifiers clash with reserved words or with other
  1000. Xidentifiers declared in the same scope,
  1001. Xthey may simply be printed.
  1002. XIn some cases the translator is forced to rename identifiers or to
  1003. Xinvent new identifiers.
  1004. X.IP operators
  1005. XThe operators +, -, *
  1006. X.I div
  1007. Xand
  1008. X.I mod
  1009. Xwhen applied to real or integer operands
  1010. Xhave exact counterparts in C and are therefore easy to handle.
  1011. XThe operator for real division, /,
  1012. Xcorresponds to the same C operator except that the operands may be integers.
  1013. XIn that case a cast is necessary.
  1014. XWhen the operands are sets the expression is converted into a function call.
  1015. X.sp
  1016. XThe operators <, <=, >, >=, = and <> all have exact counterparts in C
  1017. Xfor integer and real operands.
  1018. XMost C implementations disallows
  1019. X.I enum
  1020. Xoperands,
  1021. Xthe translator therefore casts such operands to
  1022. X.I int .
  1023. XComparisons on structures (i.e. strings or sets)
  1024. Xare converted into function calls.
  1025. X.IP assignments
  1026. XAssignments are straightforward to handle since arrays are encapsulated
  1027. Xin structures.
  1028. XTherefore:
  1029. X.DS
  1030. Xa := b
  1031. X.DE
  1032. Xbecomes
  1033. X.DS
  1034. Xa = b
  1035. X.DE
  1036. X.I unless
  1037. Xb is a string or a set,
  1038. Xin which case the assignment is converted into a function call.
  1039. X.IP indexing
  1040. XGiven the translation for array declarations (described above) we are forced
  1041. Xto translate
  1042. X.DS
  1043. Xa[i]
  1044. X.DE
  1045. Xinto
  1046. X.DS
  1047. Xa.A[i - c]
  1048. X.DE
  1049. Xwhere
  1050. X.I c
  1051. Xis the lower bound for the index type.
  1052. X.IP selection
  1053. XGiven the translation for records with variants (described above) the
  1054. Xtranslation of
  1055. X.DS
  1056. Xa.b
  1057. X.DE
  1058. Xbecomes
  1059. X.DS
  1060. Xa.b
  1061. X.DE
  1062. X.I or ,
  1063. Xif b is declared in a variant,
  1064. X.DS
  1065. Xa.Vxxx.b
  1066. X.DE
  1067. Xwhere Vxxx is a name manufactured by the translator for the particular variant.
  1068. X.IP dereferencing
  1069. XPointer references and
  1070. X.B var -parameters
  1071. Xare handled by prefixing the expression with an asterisk,
  1072. Xbut the special case dereferencing followed by selection is also recognized,
  1073. Xso:
  1074. X.DS
  1075. Xp^ := q^.f
  1076. X.DE
  1077. Xbecomes
  1078. X.DS
  1079. X*p = q->f
  1080. X.DE
  1081. X.IP miscellanea
  1082. XThe boolean operators
  1083. X.B and ,
  1084. X.B or
  1085. Xand
  1086. X.B not
  1087. Xare simply translated into their C counterparts.
  1088. XThe set contructors
  1089. X.B "[\^]" ,
  1090. Xand
  1091. X.B ".."
  1092. Xand the operator
  1093. X.B in
  1094. Xare converted to function calls.
  1095. X.bp
  1096. X.NH 1
  1097. XImplementation
  1098. X.LP
  1099. XThe general strategy is to convert the Pascal source program
  1100. Xinto a parsetree.
  1101. XThe tree is then traversed by a set of procedures that perform some
  1102. Xnecessary transformations.
  1103. XThe tree is finally traversed by a set of procedures that print the
  1104. Xcorresponding C constructs.
  1105. XThe translator consists of three major procedures that perform
  1106. Xthese actions.
  1107. XThey are augmented by a set of procedures that maintain a symbol table
  1108. Xthat holds information about identifiers found in the source,
  1109. Xand by a procedure that initializes all internal datastructures.
  1110. X.LP
  1111. XThere are three major datastructures that interact in complicated ways:
  1112. X.IP 1)
  1113. Xa store for identifiers and strings
  1114. X.IP 2)
  1115. Xa multilevel symbol table
  1116. X.IP 3)
  1117. Xa parse-tree.
  1118. X.LP
  1119. XThe identifier and string store,
  1120. X.B strstor
  1121. Xis in principle an array of characters that grow
  1122. Xin increments of one string block.
  1123. XExactly one copy of each identifier is stored in that array.
  1124. XWhenever an identifier is found in the input stream the array is
  1125. Xscanned to see if that identifier has been seen before.
  1126. XIn order to speed up the search all identifiers are represented by nodes
  1127. Xwhich are chained together such that all nodes in a particular chain
  1128. Xhave the same hashvalue as determined by the function
  1129. X.B hash .
  1130. XEach
  1131. X.B idnode
  1132. Xholds an index to strstor where the corresponding identifier text is stored.
  1133. XThe start of the hashchains are found in the global variable
  1134. X.B idtab .
  1135. X.de Ds
  1136. X.nr x \\w'\\$2'u
  1137. X.ie t \{
  1138. X.nr x \\nx/2
  1139. X.ds \\$1 \\\\h'-\\nxu'\\$2\\\\h'-\\nxu'
  1140. X.\}
  1141. X.el .ds \\$1 \\$2\\\\h'-\\nxu'
  1142. X..
  1143. X.ds l \-
  1144. X.ie t .ds a \z\*l\a
  1145. X.el   .ds a \a\z\*l
  1146. X.nr x \ntu/2
  1147. X.ds g \z\*l\\l'\nxu\&\*l'
  1148. X.ds h \\h'\nxu'
  1149. X.Ds c +
  1150. X.Ds d \(da
  1151. X.Ds u \(ua
  1152. X.Ds r \(br
  1153. X.ds s \\*r\z\*l
  1154. X.ds > \*l\z\*l\(->
  1155. X.ds < \(<-\\h'-1n'\*l
  1156. X.ds k \\kx
  1157. X.ds b \\h'|\\nxu'
  1158. X.ds t \t
  1159. X.DS L
  1160. X.lc \*l
  1161. X.fc #
  1162. Xidtab
  1163. X\*c\*a\*c
  1164. X\*r\*t\*r\*tchain of idnodes with same hashvalue
  1165. X\*c\*a\*c\*t\*c\*a\*a\*c\*t\*c\*a\*a\*c
  1166. X\*k\*r\*t\*r\*b\*h\*a#\*> #\*r\*t\*k\*t\*r\*b\*h\*a#\*> #\*r\*t\*t\*r idnode representing
  1167. X\*c\*a\*c\*t\*r\*t\*t\*r\*t\*k index=2\*b\*r\*t\*t\*r identifier "demo"
  1168. X\*r\*t\*r\*t\*c\*a\*a\*c\*t\*c\*a\*a\*c
  1169. X
  1170. X\*tstrstor
  1171. X\*c\*a\*a\*a\ \*l \*a\*a\*c
  1172. X\*r\*t\*r\*t\*r\*t\*t\*r\*t\*r
  1173. X\*k\*c\*a\*a\*a\ \*l \*a\*a\*c\*b\*h\*r
  1174. X\*h\*r
  1175. X\*h\*d
  1176. X\*c\*a\*a\*a\*a\*a\*a\*a\*a
  1177. X\*r\*t\*r\*t\*r# d #\*r# e #\*r# m #\*r# o #\*r# / #\*r
  1178. X\*c\*a\*a\*a\*a\*a\*a\*a\*a\*tfirst idblock
  1179. X\*t\*t# \*u #
  1180. X\*t\*tindex=2
  1181. X.DE
  1182. X.LP
  1183. XSo:
  1184. Xthe global representation of the identifier "demo" is a particlular
  1185. Xidnode;
  1186. Xwhenever the lexical analysis routine
  1187. Xrecognizes the identifier "demo" it returns a pointer to that idnode.
  1188. X.LP
  1189. XIn order to represent different identifiers with the same name we need to
  1190. Xbe able to distinguish between identifiers declared in different scopes.
  1191. XThis is accomplished by the
  1192. X.B symnode
  1193. Xstructures.
  1194. XWhen an identifier is first encountered in a given scope it is "declared",
  1195. Xmeaning that a new symnode is created that references the identifier.
  1196. XOccurrences of the same identifier in that scope are then represented in
  1197. Xthe parse-tree by treenodes referencing the same symnode.
  1198. X.bp
  1199. XThe program:
  1200. X.DS
  1201. Xprogram p;
  1202. X
  1203. Xvar    demo    : integer;
  1204. X
  1205. Xbegin
  1206. X    demo := 3
  1207. Xend.
  1208. X.DE
  1209. Xyilds the following structure:
  1210. X.DS L
  1211. X.lc \*l
  1212. X.fc #
  1213. X\*t# top #
  1214. X\*t# \*d #
  1215. X\*t\*c\*a\*a\*a\*a\*c treenode representing
  1216. X\*t\*k npgm\*b\*r\*t\*t\*t\*t\*r the program
  1217. X\*t\*c\*a\*s\*a\*s\*a\*s\*a\*c
  1218. X\*t\*t\*r\*t\*r\*h\*u\*t\*r\*h\*u
  1219. X\*t\*t\*r\*t\*r\*h\*r\*t\*r\*h\*c\*a\*a\*a\*a\*a\*a\*a\*g\*c
  1220. X\*t\*t\*r\*t\*r\*h\*r\*t\*c\*a\*a\*a\*a\*a\*a\*a\*c\*h\*r
  1221. X\*t\*t\*r\*t\*d\*h\*r\*t\*t\*t\*t\*t\*t\*t\*t\*r\*h\*r
  1222. X\*t\*t\*r\*h\*c\*a\*g\*s\*a\*a\*c\*k treenode representing\*b\*t\*t\*t\*t\*t\*t\*r\*h\*r
  1223. X\*t\*t\*r\*h\*k nvar\*b\*r\*t\*t\*t\*\*kr the var-declaration\*b\*t\*t\*t\*t\*t\*t\*d\*h\*r
  1224. X\*t\*t\*r\*h\*c\*g\*s\*a\*s\*a\*c\*t\*t\*t\*c\*a\*a\*a\*g\*s\*a\*c treenode repr.
  1225. X\*t\*t\*r\*t\*r\*h\*u\*t\*r\*t\*t\*t\*t\*k nassign\*b\*r\*t\*t\*t\*t\*r assignment
  1226. X\*t\*t\*r\*t\*r\*h\*r\*t\*c\*a\*k\*> to type\*b\*t\*t\*t\*c\*a\*s\*a\*a\*s\*a\*c
  1227. X\*ksymtab\*b\*t\*t\*r\*t\*d\*h\*r\*t\*t\*t\*t\*t\*t\*d\*h\*u\*t\*t\*d\*h\*u
  1228. X\*c\*a\*c\*t\*r\*h\*c\*a\*g\*s\*a\*c\*k treenode repr.\*b\*t\*t\*t\*t\*c\*a\*g\*s\*a\*c\*h\*c\*a\*g\*s\*a\*a\*c
  1229. X\*r\*t\*r \*<\*a\*c\*h\*k nid\*b\*r\*t\*t\*r\*k occurrence of\*b\*t\*t\*t\*t\*k nid\*b\*r\*t\*t\*r\*h\*k ninteger\*b\*r\*t\*t\*t\*r
  1230. X\*t\*t\*h\*c\*a\*s\*a\*c\*k id. "demo"\*b\*t\*t\*t\*t\*c\*a\*s\*a\*c\*h\*c\*a\*a\*s\*a\*c
  1231. X\*r\*t\*r\*t\*t\*r\*h\*u\*t\*t\*t\*t\*t\*t\*r\*t\*t\*t\*r\*h\*u
  1232. X\*c\*a\*c\*t\*t\*r\*h\*r\*t\*c\*a\*a\*a\*a\*a\*c\*t\*t\*t\*r\*h\*r
  1233. X\*r\*t\*r\*t\*t\*d\*h\*r\*t\*d\*t\*t\*t\*t\*t\*t\*t\*t\*d\*h\*r
  1234. X\*c\*a\*c\*t\*c\*a\*g\*s\*a\*a\*c\*k symnode representing\*b\*t\*t\*t\*t\*t\*t\*c\*a\*g\*s\*a\*g\*c
  1235. X\*r\*k\*t\*r\*b\*h\*a\*>\*t\*k lidentifier\*b\*r\*t\*t\*t\*r\*k identifier "demo"\*b\*t\*t\*t\*t\*t\*t\*k linteger\*b\*r\*t\*t\*h\*r
  1236. X\*c\*a\*c\*t\*c\*a\*s\*a\*a\*c\*k in the current scope\*b\*t\*t\*t\*t\*t\*t\*k linum=3\*b\*r\*t\*t\*h\*r
  1237. X\*t\*t\*t\*r\*t\*t\*t\*t\*t\*t\*t\*t\*c\*a\*a\*g\*c
  1238. X\*kidtab\*b\*t\*t\*t\*c\*a\*a\*a\*c
  1239. X\*c\*a\*c\*t\*t\*t\*t\*t\*r
  1240. X\*r\*t\*r\*t\*t\*t\*t\*t\*d
  1241. X\*c\*a\*c\*t\*c\*a\*a\*c\*t\*c\*a\*a\*c
  1242. X\*k\*r\*t\*r\*b\*h\*a#\*> #\*r\*t\*k\*t\*r\*b\*h\*a#\*> #\*r\*t\*t\*r idnode representing
  1243. X\*c\*a\*c\*t\*r\*t\*t\*r\*t\*k index=2\*b\*r\*t\*t\*r identifier "demo"
  1244. X\*r\*t\*r\*t\*c\*a\*a\*c\*t\*c\*a\*a\*c
  1245. X
  1246. X\*tstrstor
  1247. X\*c\*a\*a\*a\ \*l \*a\*a\*c
  1248. X\*r\*t\*r\*t\*r\*t\*t\*r\*t\*r
  1249. X\*c\*g\*s\*a\*a\*a\ \*l \*a\*a\*c
  1250. X\*h\*r
  1251. X\*h\*d
  1252. X\*c\*a\*a\*a\*a\*a\*a\*a\*a
  1253. X\*r\*t\*r\*t\*r# d #\*r# e #\*r# m #\*r# o #\*r# / #\*r
  1254. X\*c\*a\*a\*a\*a\*a\*a\*a\*a\*tfirst idblock
  1255. X\*t\*t# \*u #
  1256. X\*t\*tindex=2
  1257. X.fc
  1258. X.lc
  1259. X.DE
  1260. XWe see that the two occurrences of the identifier "demo" are represented by
  1261. Xtwo
  1262. X.B treenodes
  1263. Xof variant
  1264. X.B nid
  1265. Xthat both have pointers to the same
  1266. X.B symnode
  1267. Xrepresenting the declaration of "demo".
  1268. XAll symnodes at a given declarationlevel are chained together (in the
  1269. Xsame manner as the idnodes) and the chains are attached to the global
  1270. Xvariable
  1271. X.B symtab .
  1272. XIn order to find out if an identifer is declared in the current scope we
  1273. Xscan the chain of symnodes starting from symtab, and check if any of them
  1274. Xreferences the idnode we are looking for.
  1275. XA symnode also have a pointer to the treenode which defines the symbol.
  1276. XThe
  1277. X.B symtabs
  1278. Xthemselves are also chained,
  1279. Xthe chain implements a stack of declarationlevels.
  1280. XThe symtab which is created when the scope of a procedure is entered
  1281. Xis also attached to that procedure.
  1282. XWhen a procedure is entered we create a new symtab, push it onto the stack,
  1283. Xparse the procedure and pop the stack.
  1284. XThe symbols then visible are those that still can be reached from the stack.
  1285. X.LP
  1286. XThe parse-tree consists of
  1287. X.B treenodes
  1288. Xrepresenting each declaration, statement, expression etc.
  1289. XEach node except the nprogram node
  1290. Xhas a pointer to its immediate father (giving the defining point),
  1291. Xto its children (if it has any) and to its right brother (if it is
  1292. Xa member of a list).
  1293. XThe top of the tree is found in the global variable
  1294. X.B top .
  1295. X.LP
  1296. XIn order to find the defining point for the identifier in the assignment,
  1297. Xwe follow pointers from the nassign-treenode
  1298. Xto the nid-treenode, to the lidentifier-symnode,
  1299. Xand then up to the nid-treenode in the declaration.
  1300. XIf we want to know the type of the identifier
  1301. Xwe proceed up to the nvar-treenode
  1302. Xand then down to the node giving the type in the declaration
  1303. X(in our example that node would also be a nid-treenode referencing a
  1304. Xlinteger-symnode that represents the identifier "integer").
  1305. XThere is a function
  1306. X.B typeof
  1307. Xthat performs exactly this operation.
  1308. XIt will return a pointer to a npredef-, nsubrange-, nscalar-, nptr-
  1309. Xnarray-, nrecord-, nfileof- or nsetof-treenode.
  1310. XIn those cases where the translator pays attention to types
  1311. Xit uses a pointer (obtained from typeof) as representation of a type.
  1312. X.LP
  1313. XGiven the parse-tree and the layered symbol table
  1314. Xit is not hard to see how the translations described earlier are performed.
  1315. XThe one place where the code becomes more than usually complex is when a
  1316. X.B write
  1317. Xstatement with format specifications is to be translated into a call to
  1318. X.B fprintf .
  1319. X.bp
  1320. X.NH 1
  1321. XTuning
  1322. X.LP
  1323. XThe behaviour of the translator may be modified for some cases simply
  1324. Xby changing constants.
  1325. XThese constants are all located at the top of the program text.
  1326. X.IP output 12
  1327. XThe translator will copy the source during input if the constant
  1328. X.B echo
  1329. Xis true.
  1330. XThe copy is preceeded by the line
  1331. X.DS
  1332. X# ifdef PASCAL
  1333. X.DE
  1334. Xand ended by the line
  1335. X.DS
  1336. X# else
  1337. X.DE
  1338. Xand then follows the translated code
  1339. Xand finally
  1340. X.DS
  1341. X# endif
  1342. X.DE
  1343. XThis may be used to hold both Pascal and C source in the same file.
  1344. XIf the Pascal part is changed the C part may be updated through:
  1345. X.DS
  1346. X    cpp -P -DPASCAL < orig > tmp
  1347. X    ptc < tmp > new
  1348. X    move new orig
  1349. X.DE
  1350. Xassuming that
  1351. X.B echo
  1352. Xis true and that 
  1353. X.B cpp
  1354. Xis the standard C preprocessor.
  1355. X.DS
  1356. XDefault value:
  1357. X
  1358. X    echo        = false;
  1359. X.DE
  1360. X.IP comments
  1361. XThe translator recognizes both (* and { as comment delimiters.
  1362. XThey are treated as different,
  1363. Xallowing 1 level nested comments,
  1364. Xif the constant
  1365. X.B diffcom
  1366. Xis true.
  1367. X.DS
  1368. XDefault value:
  1369. X
  1370. X    diffcomm    = false;
  1371. X.DE
  1372. X.IP symbols
  1373. XThe translator accepts default entries in case-statements provided
  1374. Xthat the keyword defined through
  1375. X.B othersym
  1376. Xis used in place of the constant list.
  1377. X.DS
  1378. XDefault value:
  1379. X
  1380. X    othersym    = 'otherwise ';
  1381. X.DE
  1382. Xsubstitute for
  1383. X.DS
  1384. X    othersym    = 'otherwise%';
  1385. X.DE
  1386. Xif that feature is undesired.
  1387. X.IP
  1388. XThe translator accepts externally declared procedures and functions
  1389. Xprovided that the directive defined through
  1390. X.B externsym
  1391. Xis used in place of the keyword
  1392. X.B forward .
  1393. X.DS
  1394. XDefault value:
  1395. X
  1396. X    externsym    = 'external  ';
  1397. X.DE
  1398. X.IP sets
  1399. XSets are implemented as arrays of
  1400. X.B wordtype .
  1401. XThe type is assumed to hold
  1402. X.B "setbits + 1"
  1403. Xbits numbered from 0.
  1404. X.DS
  1405. XDefault value:
  1406. X
  1407. X    wordtype    = 'unsigned short';
  1408. X    setbits    = 15;
  1409. X.DE
  1410. X.ne 10
  1411. X.IP files
  1412. XThe implementation of files uses a flag-word which has the type given as
  1413. X.B filebits
  1414. Xwhich is assumed to hold
  1415. X.B "filefill + 4"
  1416. Xbits.
  1417. X.DS
  1418. XDefault value:
  1419. X
  1420. X    filebits    = 'unsigned short';
  1421. X    filefill    = 12;
  1422. X.DE
  1423. X.ne 20
  1424. X.IP stmts
  1425. XIf the Pascal source is known to be "normal" in the sense that for-loops
  1426. Xalways have an upper bound that is less than the maximum value of the
  1427. Xtype of the loop-variable, and in the sense that the upper bound doesn't
  1428. Xchange by computations inside the loop, then the translator may generate
  1429. Xa more natural code.
  1430. XI.e:
  1431. X.DS
  1432. Xfor i := 1 to 10 do ;
  1433. X.DE
  1434. Xbecomes
  1435. X.DS
  1436. Xfor (i = 1; i <= 10; i++) ;
  1437. X.DE
  1438. XSince the requirements cannot be determined by the translator itself
  1439. Xthis kind of code is generated when the constant
  1440. X.B lazyfor
  1441. Xis true.
  1442. X.DS
  1443. XDefault value:
  1444. X
  1445. X    lazyfor    = false;
  1446. X.DE
  1447. X.ne 10
  1448. X.IP new
  1449. XThe second and following parameters to the procedure
  1450. X.B new
  1451. Xwill be ignored if the constant
  1452. X.B unionnew
  1453. Xis false.
  1454. X.DS
  1455. XDefault value:
  1456. X
  1457. X    unionnew    = true;
  1458. X.DE
  1459. X.ne 10
  1460. X.IP strings
  1461. XAll identifiers and strings are stored in the translator with the special
  1462. Xcharacter having the ordinal value
  1463. X.B null
  1464. Xas endmarker.
  1465. XHence, that character can not occur in strings in the Pascal source.
  1466. X.DS
  1467. XDefault value:
  1468. X
  1469. X    null        = 0;
  1470. X.DE
  1471. X.ne 20
  1472. X.IP types
  1473. XThe names of predefined types are given by the constants:
  1474. X.B inttyp ,
  1475. X.B chartyp ,
  1476. X.B floattyp ,
  1477. Xand
  1478. X.B doubletyp .
  1479. X.DS
  1480. XDefault value:
  1481. X
  1482. X    inttyp        = 'int';
  1483. X    chartyp    = 'char';
  1484. X    floattyp    = 'float';
  1485. X    doubletyp    = 'double';
  1486. X.DE
  1487. XThe typename for real variables and functions defined by the user
  1488. Xis given by the constant
  1489. X.B realtyp .
  1490. X.DS
  1491. XDefault value:
  1492. X
  1493. X    realtyp    = doubletyp;
  1494. X.DE
  1495. XThe typename for procedures is given by the constant
  1496. X.B voidtyp .
  1497. X.DS
  1498. XDefault value:
  1499. X
  1500. X    voidtyp    = 'void';
  1501. X.DE
  1502. X.ne 10
  1503. X.IP i/o
  1504. XThe default fieldwidths for integer and real values written on textfiles
  1505. Xare given by the constants
  1506. X.B intlen
  1507. Xand
  1508. X.B fixlen .
  1509. X.DS
  1510. XDefault value:
  1511. X
  1512. X    intlen    = 10;
  1513. X    fixlen    = 20;
  1514. X.DE
  1515. X.IP types
  1516. XA table in the translator gives the mapping from Pascal
  1517. Xinteger subrange types to C arithmetic types.
  1518. XThe table is initialized by code located at the end of procedure
  1519. X.I initialize
  1520. Xgiving the following default configuration:
  1521. X.TS
  1522. Xl l l
  1523. Xr r l .
  1524. XLow bound    High bound    Selected type
  1525. X.sp
  1526. X0    255    unsigned char
  1527. X-128    127    char
  1528. X0    65535    unsigned short
  1529. X-32768    32767    short
  1530. X-2147483647    2147483647    long
  1531. X.TE
  1532. END_OF_FILE
  1533. if test 35411 -ne `wc -c <'ptoc.doc'`; then
  1534.     echo shar: \"'ptoc.doc'\" unpacked with wrong size!
  1535. fi
  1536. # end of 'ptoc.doc'
  1537. fi
  1538. echo shar: End of archive 5 \(of 12\).
  1539. cp /dev/null ark5isdone
  1540. MISSING=""
  1541. for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
  1542.     if test ! -f ark${I}isdone ; then
  1543.     MISSING="${MISSING} ${I}"
  1544.     fi
  1545. done
  1546. if test "${MISSING}" = "" ; then
  1547.     echo You have unpacked all 12 archives.
  1548.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1549. else
  1550.     echo You still need to unpack the following archives:
  1551.     echo "        " ${MISSING}
  1552. fi
  1553. ##  End of shell archive.
  1554. exit 0
  1555. -- 
  1556.  
  1557. Rich $alz            "Anger is an energy"
  1558. Cronus Project, BBN Labs    rsalz@bbn.com
  1559. Moderator, comp.sources.unix    sources@uunet.uu.net
  1560.